package py.org.atom.seam;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.persistence.Query;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.FlushModeType;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.datamodel.DataModel;
import org.jboss.seam.core.Conversation;
import org.jboss.seam.international.Messages;

import py.org.atom.seam.util.ContextUtil;
import py.org.atom.seam.util.Sys;
import py.org.atom.seam.util.UString;

@Scope(ScopeType.CONVERSATION)
public class BaseAdmin<E> extends BaseSIUD<E>{
	
    protected Map<String, Object> queryParms = new HashMap<String, Object>();
    
    protected List<Order> queryOrder = new ArrayList<Order>();
    
    protected boolean checkAll = false;
    
	@DataModel
	protected List<E> resultList;    	
	
	protected int page = 1;
	protected int pages = 0;
	protected int total = 0;
	protected Boolean exists = null;
	protected String selectCount;
	protected String search;
	protected String count;
	
	protected Integer maxRows = null;
	
	protected List<Integer> pagesList;
	

    public List<E> getResultList() {
		return resultList;
	}

	public void setResultList(List<E> resultList) {
		this.resultList = resultList;
	}
	
	public void find(){
		this.checkAll = false;
		this.queryOrder = new ArrayList<Order>(); 
    	this.goToPage(1);
	}
	
	@SuppressWarnings("unchecked")
	public void goToPage(int pag){
	
		
		if(UString.isEmpty(this.search))
			return;
		
		this.loadedInstance = false;
		
		String order = this.getStringOrder();
		
		String jquery = this.search + order;
		
		Query qSearch = this.getQuery(jquery);
		Query qCount = this.getQuery(this.count);
		
		Number cant = (Number)qCount.getSingleResult();
		
		if(cant == null || cant.intValue() <= 0){
			this.exists = false;
        	String msg = Messages.instance().get("py.org.atom.NoDataDisplay");
        	this.info(msg);		
			return;
		}
		
		this.total = cant.intValue();
		this.pages = (this.total / this.maxRows) + (this.total % this.maxRows > 0 ? 1 : 0);
		this.page = pag;
		int ini = (this.page > 0 ? this.page - 1 : 0);
		
		this.resultList = qSearch.setMaxResults(this.maxRows)
							.setFirstResult(ini * this.maxRows)
							.getResultList();
		
		
		
		String msg = Messages.instance().get("py.org.atom.Showing");
		
		this.info(msg + " " + cant + "/"+ this.getTotalCount());
		
		this.exists = true;
		
		
	}
	
	@SuppressWarnings("unchecked")
	private Query getQuery(String jpaQuery){
		
		Query q = this.entityManager.createQuery(jpaQuery);

		Iterator it = this.queryParms.keySet().iterator();

		while (it.hasNext()) {
			String k = (String) it.next();
			if (k != null) {
				Object o = (Object) this.queryParms.get(k);
				q.setParameter(k, o);
			}
		}		
		
		return q;
	}

	private String getStringOrder(){
		
		String sOrder = "";
		if(this.queryOrder != null && this.queryOrder.size() > 0){
			sOrder += " order by ";
			
			for(int i = 0; i<this.queryOrder.size(); i++){
				if(UString.isEmpty(((Order)this.queryOrder.get(i)).getName())){
					sOrder = "";
					i = this.queryOrder.size();
				}
				if(UString.isEmpty(((Order)this.queryOrder.get(i)).getDirection())){
					sOrder = "";
					i = this.queryOrder.size();
				}				
				
				sOrder += ((Order)this.queryOrder.get(i)).getName() + " " + ((Order)this.queryOrder.get(i)).getDirection();
				if((i + 1) < this.queryOrder.size())
					sOrder += ",";
			}
			
		}
		return sOrder;
	}
	
	protected Integer getTotalCount(){
		
		if(this.selectCount == null)
			return null;
		
		Number cant = (Number)this.entityManager.createQuery(this.selectCount).getSingleResult();
		
		if(cant == null)
			return null;
		
		return cant.intValue();
	}
	
	public void first(){
		this.goToPage(1);
	}

	public void previous(){
		if(this.page > 0)
			this.goToPage(this.page - 1);
	}	
	
	public void next(){
		this.goToPage(this.page + 1);
	}

	public void last(){
		this.goToPage(this.pages);
	}	
	
	public void clearOrder(){
		this.queryOrder = new ArrayList<Order>();
		this.goToPage(this.page);
	}
	
	public void setOrderCol(String col, String dir){
		if(col == null)
			return;
		if(dir == null)
			return;
		String label = col;
		col = "o." + col;
		this.setOrderCol(label, col, dir);
	}
	
	public void setOrderCol(String label, String col, String dir){
		Order obj = new Order(col,dir,label);
		boolean add = true;
		for(int i=0; i<this.queryOrder.size(); i++){
			if(this.queryOrder.get(i).getName().trim().equals(obj.getName())){
				this.queryOrder.get(i).setDirection(dir);
				add = false;
				break;
			}
		}
		if(add)
			this.queryOrder.add(obj);
		this.goToPage(this.page);
	}	
	
	public void delOrderCol(String name){
		for(int i=0; i<this.queryOrder.size(); i++){
			if(this.queryOrder.get(i).getName().trim().equals(name)){
				this.queryOrder.remove(i);
				break;
			}
		}
		this.goToPage(this.page);
	}
	
	public List<Order> getQueryOrder() {
		return queryOrder;
	}

	public void setQueryOrder(List<Order> queryOrder) {
		this.queryOrder = queryOrder;
	}

	public void clearResults(){
		this.resultList = null;
		this.setCheckAll(false);
		this.queryParms = new HashMap<String, Object>();
		this.queryOrder = new ArrayList<Order>();
		this.page = 1;
		this.pages = 0;
		this.total = 0;
	}

	public void doCheckAll(){
		if(this.resultList != null && this.resultList.size() > 0){
			if(this.checkAll){ 
				for(int i=0; i<this.resultList.size();i++)
					((py.org.atom.seam.entity.Base)this.resultList.get(i))
						.setSelected(true);
			}else{
				for(int i=0; i<this.resultList.size();i++)
					((py.org.atom.seam.entity.Base)this.resultList.get(i))
						.setSelected(false);				
			}
		}		
	}	
	
	public List<Integer> getPagesList() {
		this.pagesList = new ArrayList<Integer>();
		for(int i=1;i<=this.pages;i++)
			this.pagesList.add(i);
		return pagesList;
	}

	public void setPagesList(List<Integer> pagesList) {
		this.pagesList = pagesList;
	}

	public int getPage() {
		return page;
	}

	public void setPage(int page) {
		this.page = page;
	}

	public int getPages() {
		return pages;
	}

	public void setPages(int pages) {
		this.pages = pages;
	}

	public int getTotal() {
		return total;
	}

	public void setTotal(int total) {
		this.total = total;
	}	
	
	public String getSearch() {
		return search;
	}

	public void setSearch(String search) {
		this.search = search;
	}

	public String getCount() {
		return count;
	}

	public void setCount(String count) {
		this.count = count;
	}	
	
	public String getSelectCount() {
		return selectCount;
	}

	public void setSelectCount(String selectCount) {
		this.selectCount = selectCount;
	}

	public Boolean getExists() {
		return exists;
	}

	public void setExists(Boolean exists) {
		this.exists = exists;
	}

	public boolean isCheckAll() {
		return checkAll;
	}

	public void setCheckAll(boolean checkAll) {
		this.checkAll = checkAll;
	}

	public int getMaxRows() {
		if(this.maxRows == null){
			this.maxRows = Sys.intProperty("default.rownum");
			if(this.maxRows < 0)
				this.maxRows = 10;
		}
		return maxRows;
	}

	public void setMaxRows(int maxRows) {
		this.maxRows = maxRows;
	}
	
	
}
